/**
 * @author Gabriel Tuma, Sebastian Demler
 * 
 * The Model Class. 
 * This Class is Observable
 * Contains the Application Data
 */
/*
 * Modifications / To do:
 * Load + save options --> Menu updatet sich nur wenn ich drauf wieder clicke
 */


package com.android.datecalculator;

import java.util.Observable;

import android.content.Context;
import android.view.MenuItem;

public class Model extends Observable {
	
	private final String OPTIONS_FILE_NAME = "dc.options.data";
	
	private Context context;
	private Core core;				// Core/Controller	
	private DCOptions options;		// Options
	private boolean newinstall;
	private long start,				// Start date in Milliseconds
				 end;				// End date in Milliseconds

	/**
	 * Constructor
	 */
	public Model(Context context) {
		this.context 	= context;
		this.core 	 	= new Core();
		this.newinstall	= false;
		if(!__loadOptions()) {
			newinstall = true;
			try {
				this.core.writeDCOptions(this.context, this.options, OPTIONS_FILE_NAME);
			} catch (Exception ex){
				this.core.catched_exception(ex, context, null, false, false);
			}
		}
		
	}
	
	
	
	/* 
	 * ***********************************************************************
	 * 							Getter
	 * ***********************************************************************
	 */
	
	/**
	 * If new installed
	 * @return
	 */
	public boolean newinstalled() {
		return newinstall;
	}

	/**
	 * Get the start value
	 * @return Milliseconds
	 */
	public long getStart() {
		return start;
	}
	
	/**
	 * Get the end value
	 * @return Milliseconds
	 */
	public long getEnd() {
		return end;
	}
	
	/**
	 * Get the Options
	 */
	public DCOptions getOptions() {
		return options;
	}
	
	
	
	/* 
	 * ***********************************************************************
	 * 							Setter
	 * ***********************************************************************
	 */
	
	/**
	 * Set the start value and notify the view about the changes
	 * @param year
	 * @param monthOfYear
	 * @param dayOfMonth
	 */
	public void setStart(int year, int monthOfYear, int dayOfMonth) {
		start = core.getDateMillis(year, monthOfYear, dayOfMonth);
		setChanged();			// Sets the changed flag for this Observable
		notifyObservers();		// If hasChanged() returns true, calls the update() method for every observer in the list of observers using null as the argument. Afterwards, calls clearChanged().	
	}
	
	/**
	 * Set the end value and notify the view about the changes
	 * @param year
	 * @param monthOfYear
	 * @param dayOfMonth
	 */
	public void setEnd(int year, int monthOfYear, int dayOfMonth) {
		end = core.getDateMillis(year, monthOfYear, dayOfMonth);
		setChanged();
		notifyObservers();
	}
	
	
	
	/* 
	 * ***********************************************************************
	 * 							Public Methodes
	 * ***********************************************************************
	 */
	
	/**
	 * Calculate the difference and return it.
	 * @return Milliseconds
	 */
	public long calcDiff(){
		return core.calcDiff(start, end, options.getDifference_unit());
	}
	
	/**
	 * Write the Options and notify the Observer
	 * @param difference_unit
	 */
	public boolean commitOptions(){
		boolean error = false;
		
		try {
			
			core.writeDCOptions(context, options, OPTIONS_FILE_NAME);
			
		} catch (Exception ex) {
			
			error = true;
		} 
		
		if(error) {
			core.catched_exception(null, context, context.getString(R.string.error_save_options), false, true);
			__loadOptions();
		}
		
		setChanged();
		notifyObservers();
		return !error;
	}
	
	public void switchDifferenceUnit(MenuItem item) {
		
		if(options.getDifference_unit() == DifferenceUnits.HOURS){
    		
    		options.setDifference_unit(DifferenceUnits.DAYS);
    		if(commitOptions())
	    		item.setTitle( String.format(context.getString(R.string.menu_switch), __getString(DifferenceUnits.HOURS)) );
    		
    	} else {
    		
    		options.setDifference_unit(DifferenceUnits.HOURS);
    		if(commitOptions()) {
	    		item.setTitle( String.format(context.getString(R.string.menu_switch), __getString(DifferenceUnits.DAYS)) );
    		}
    		
    	}
		
	}
	
	public void setTitleMenuItemSwitchDU(MenuItem item){
        if(getOptions().getDifference_unit() == DifferenceUnits.HOURS)
    		
        	item.setTitle( 
        			String.format(
    					context.getString(R.string.menu_switch), 
    					__getString(DifferenceUnits.DAYS) )
    					);
    	else
    		
    		item.setTitle(
    				String.format(
    					context.getString(R.string.menu_switch), 
    					__getString(DifferenceUnits.HOURS) )
    					);
	}
	
	
	/* 
	 * ***********************************************************************
	 * 							Private Methodes
	 * ***********************************************************************
	 */
	
	/**
	 * if returns true 	--> loasDCOptions was successful <br>
	 * if returns false	--> load default Options
	 * @return
	 */
	private boolean __loadOptions(){
		try { 
			
			options = core.readDCOptions(context, OPTIONS_FILE_NAME);
			return true;
			
		} catch (Exception ex){
			
			options = new DCOptions();
			
		}
		return false;
	}
	
	/**
	 * 
	 * @param unit
	 * @return
	 */
	private String __getString(DifferenceUnits unit){
		if(DifferenceUnits.HOURS == unit)
			return context.getString(R.string.diff_unit_hours);
		
		return context.getString(R.string.diff_unit_day);
	}
	
}
